---
id: quick-start
title: Quick Start
slug: /getting-started/quick-start/
description: Get up an running with Relay
keywords:
- quick
---
This quick start guide will start with a new React app using Vite and show you how to add Relay to it.

:::tip
If you'd prefer an automated approach, [`create-relay-app`](https://github.com/tobias-tengler/create-relay-app) by Tobias Tengler will walk you through adding Relay to an existing React app via a series of prompts: `npm create @tobiastengler/relay-app`
:::

We will be building a simple app which shows Star Wars movies fetched from the [example Star Wars GraphQL API](https://graphql.org/swapi-graphql/) hosted by graphql.org.

## Scaffold a React App

We’ll start with a [Vite](https://vite.dev/) React app using TypeScript.

```bash
npm create vite -- --template react-ts
```

You’ll be prompted for a project name. Type: `relay-example`

## Install Dependencies

```bash
cd relay-example

# Runtime dependencies
npm install relay-runtime react-relay
# Dev dependencies
npm install --save-dev babel-plugin-relay graphql relay-compiler
# Types
npm install --save-dev @types/relay-runtime @types/react-relay
```

## Configure Vite to use Relay

Relay uses a [Babel plugin](./babel-plugin.mdx) to insert code generated by the Relay compiler into your bundle. We can enable the Relay Babel plugin we installed earliery by configuring the React Vite plugin.

```tsx title="vite.config.ts"
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vite.dev/config/
export default defineConfig({
  plugins: [
    // change-line
    react({ babel: { plugins: ["relay"] } })
  ],
})
```

See [Babel Plugin](./babel-plugin.mdx) for information about how to configure the Babel plugin for other build systems.

## Configure the Relay Compiler

Next we will download the GraphQL schema for the Star Wars GraphQL endpoint.

```bash
curl -O https://raw.githubusercontent.com/graphql/swapi-graphql/refs/heads/master/schema.graphql
```

And define our `relay.config.json` config file which tells the [Relay Compiler](./compiler.mdx) which schema file we want it to use and other details about our project.

```json title="relay.config.json"
{
  "src": "./src",
  "schema": "./schema.graphql",
  "language": "typescript"
}
```

See [Relay Compiler](./compiler.mdx) for more information about configuring and running the Relay compiler.

## Configure your Relay Environment

To allow components within our application to fetch GraphQL we configure a Relay Environment to fetch from our test endpoint and add it to React context.

```tsx title="src/main.tsx"
import { StrictMode, Suspense } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.tsx";
import { RelayEnvironmentProvider } from "react-relay";
import { Environment, Network, FetchFunction } from "relay-runtime";

const HTTP_ENDPOINT = "https://graphql.org/graphql/";

const fetchGraphQL: FetchFunction = async (request, variables) => {
  const resp = await fetch(HTTP_ENDPOINT, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ query: request.text, variables }),
  });
  if (!resp.ok) {
    throw new Error("Response failed.");
  }
  return await resp.json();
};

const environment = new Environment({
  network: Network.create(fetchGraphQL),
});

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <RelayEnvironmentProvider environment={environment}>
      <Suspense fallback="Loading...">
        <App />
      </Suspense>
    </RelayEnvironmentProvider>
  </StrictMode>
);
```

See [Relay Environment](../api-reference/relay-runtime/relay-environment.mdx) for an overview of the Relay Environment and how to configure it.

:::tip
`<RelayEnvironmentProvider>` exposes your Environment via [React context](https://react.dev/learn/passing-data-deeply-with-context), so it must wrap your entire application.
:::

## Define your first Relay component

Finally we can start defining the data we want to fetch and build our UI. Our app will fetch a list of films and render each one using a `<Film>` component.

```tsx title="src/App.tsx"
import { AppQuery } from "./__generated__/AppQuery.graphql";
import { graphql, useLazyLoadQuery } from "react-relay";
import Film from "./Film";

export default function App() {
  const data = useLazyLoadQuery<AppQuery>(
    graphql`
      query AppQuery {
        allFilms {
          films {
            id
            ...Film_item
          }
        }
      }
    `,
    {}
  );

  const films = data?.allFilms?.films?.filter((film) => film != null);

  return (
    <div>
      <h1>Star Wars Films</h1>
      {films?.map((film) => (
        <Film key={film.id} film={film} />
      ))}
    </div>
  );
}
```

## Define your first fragment

One of Relay's core principles is that each component should define its own data dependencies. So, we define our `<Film>` component using a [GraphQL Fragment](https://graphql.org/learn/queries/#fragments).

```typescript title="src/Film.tsx"
import { graphql, useFragment } from "react-relay";
import type { Film_item$key } from "./__generated__/Film_item.graphql";

export default function FilmListItem(props: { film: Film_item$key; }) {
  const film = useFragment<Film_item$key>(
    graphql`
      fragment Film_item on Film {
        title
        director
      }
    `,
    props.film
  );

  return (
    <li>
      <b>{film.title}</b>: directed by <i>{film.director}</i>
    </li>
  );
}
```

## Compile and run your app

All that’s left is to run the Relay compiler and start your app!

The Relay compiler generates TypeScript types and combines your queries and fragments into optimized representations. You have to run the Relay compiler each time you modify your GraphQL queries or fragments.

:::tip
If you have [Watchman](https://facebook.github.io/watchman/) installed you can run `npx relay-compiler --watch` to have the compiler run in watch mode, but you'll need to run `echo "{}" > .watchmanconfig` to create a Watchman root.
:::

```bash
npx relay-compiler
npm run dev
```

You should now be able to open your app in a browser: [http://localhost:5173/](http://localhost:5173/)

May the force be with you!
